package com.linjiu.gson;

import android.os.Build;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.hjq.gson.factory.GsonFactory;
import com.linjiu.gson.tool.ErrorCallBack;
import com.linjiu.gson.tool.GsonErrorBack;
import com.linjiu.gson.tool.GsonErrorBean;


import java.lang.reflect.Type;

/**
 * 项目名称：com.linjiu.base.net
 * 创建人:LuoFG
 * 创建时间:2022/11/17  16:47
 * 描述:
 * 作用:
 */
public class GsonClient {

    private volatile  static GsonClient instance=null;
    public Gson mGson;

    public GsonClient() {
        // 获取单例的 Gson 对象（已处理容错）
        mGson = GsonFactory.getSingletonGson();
    }

    public static GsonClient getInstance(){
        if(instance==null){
            synchronized (GsonClient.class){
                if(instance==null){
                    instance=new GsonClient();
                }
            }
        }
        return instance;
    }
    //Gson总的错误输出
    private GsonErrorBack gsonErrorBack=null;

    public GsonClient setGsonErrorBack(GsonErrorBack gsonErrorBack) {
        this.gsonErrorBack = gsonErrorBack;
        return this;
    }

    /**
     * 可自行设置Gson
     * @param mGson
     */
    public void setGson(Gson mGson) {
        this.mGson = mGson;
    }

    /**
     * Gson 转换  集中处理  避免转换异常
     * @param data
     * @param classOfT
     * @param backs
     * @param <T>
     * @return
     */
    public  <T>T transGson(Object data, Class<T> classOfT, ErrorCallBack... backs){

        T result= transGsonData(data, classOfT, new ErrorCallBack() {
            @Override
            public void errorBack(Exception e) {
                if(backs!=null&&backs.length!=0){
                    backs[0].errorBack(e);
                }
            }
        });
        //解析没报错  但是对象为空
        if(result==null){
            if(backs!=null&&backs.length!=0){
                backs[0].errorBack(new Exception("empty"));
            }
        }

        return result;
    }

    /**
     * Gson 转换  集中处理  避免转换异常
     * @param data
     * @param type
     * @param backs
     * @param <T>
     * @return
     */
    public  <T>T transGson(Object data, Type type, ErrorCallBack... backs) {

        T result = transGsonDataType(data, type, new ErrorCallBack() {
            @Override
            public void errorBack(Exception e) {
                if (backs != null && backs.length != 0) {
                    backs[0].errorBack(e);
                }
            }
        });

        return result;
    }


    /**
     * 获取json信息  String输出
     * @param data
     * @return
     */
    public  String getGsonStr(Object data){
        String result="";
        try {
            result=mGson.toJson(data);
        } catch (Exception e) {
            e.printStackTrace();
            result="";
            //Log.e("AppSetUtils getGsonStr","getGson error");
        }

        return result;
    }


    private  <T>T transGsonData(Object data, Class<T> classOfT, ErrorCallBack... backs){
        T transt=null;
        try {
            if(data instanceof String) {
                String dataTrans=(String)data;
                transt = mGson.fromJson(dataTrans, classOfT);
            }else {
                transt = mGson.fromJson(mGson.toJson(data), classOfT);
            }
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            if(gsonErrorBack!=null){
                gsonErrorBack.errorBack(new GsonErrorBean(e,data,classOfT.getName()));
            }

            if(backs!=null&&backs.length!=0){
                backs[0].errorBack(e);
            }
        }

        return transt;
    }

    private <T>T transGsonDataType(Object data, Type type, ErrorCallBack... backs){
        T transt=null;
        try {
            if(data instanceof String) {
                String dataTrans=(String)data;
                transt = mGson.fromJson(dataTrans, type);
            }else {
                transt = mGson.fromJson(mGson.toJson(data), type);
            }
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            if(gsonErrorBack!=null){
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                    gsonErrorBack.errorBack(new GsonErrorBean(e,data,"type="+type.getTypeName()));
                }else{
                    gsonErrorBack.errorBack(new GsonErrorBean(e,data,"type=otherType"));
                }
            }

            if(backs!=null&&backs.length!=0){
                backs[0].errorBack(e);
            }
        }

        return transt;
    }
}
